﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IvyBus;
using System.Windows.Media.Media3D;

namespace DisplayInteraction1
{
    class ModelProto2Bis
    {
        private static Ivy bus;
        private static Boolean rightHandOpened = true;
        private static Point3D rightHandPos;
        private String adresse;
        private static bool displayReady = false;
        private static bool kinectReady = false;
        private static MainWindow window;

        enum States
        {
            LIBRE,
            DESSIN,
            EFFACE
        }

        static States etat;

        public ModelProto2Bis(String adresse, MainWindow window)
        {
            this.adresse = adresse;
            ModelProto2Bis.window = window;
            bus = new Ivy("MODELPROTO2BIS", "MODELPROTO2BIS READY");
            etat = States.LIBRE;
        }

        public void start()
        {
            bus.Start(this.adresse);
            bus.BindMsg("^IHM_EVENT=(.*)", viewReady);
            bus.BindMsg("^USER_EVENT=(.*)", user);
            bus.BindMsg("^HAND_RIGHT_POSITION X=(.*) Y=(.*) Z=(.*)", newRightHandPosition);
            bus.BindMsg("^HAND_RIGHT_EVENT=(.*)", rightHandEvent);
        }


        EventHandler<IvyMessageEventArgs> viewReady = new EventHandler<IvyMessageEventArgs>(t0);
        static void t0(Object o, IvyMessageEventArgs a)
        {
            switch (a.GetArguments()[0])
            {
                case "ASK_CONNECTION":
                    displayReady = true;
                    getReady();
                    break;
                case "END_CONNECTION":
                    displayReady = false;
                    getReady();
                    break;
                default:
                    Console.WriteLine("SYNTAXE ERROR MESSAGE IVY IHM_EVENT");
                    break;
            }
        }

        EventHandler<IvyMessageEventArgs> user = new EventHandler<IvyMessageEventArgs>(t1);
        static void t1(Object o, IvyMessageEventArgs a)
        {
            switch (a.GetArguments()[0])
            {
                case "DETECTED":
                    kinectReady = true;
                    getReady();
                    break;
                case "LOST":
                    kinectReady = false;
                    getReady();
                    send("KINECT_EVENT=USER_LOST");
                    break;
                default:
                    Console.WriteLine("SYNTAXE ERROR MESSAGE IVY USER_EVENT");
                    break;
            }
        }

        EventHandler<IvyMessageEventArgs> newRightHandPosition = new EventHandler<IvyMessageEventArgs>(t2);
        static void t2(Object o, IvyMessageEventArgs a)
        {
            rightHandPos = new Point3D(Double.Parse(a.GetArguments()[0]), double.Parse(a.GetArguments()[1]), double.Parse(a.GetArguments()[2]));
            send("KINECT_POSITION X=" + rightHandPos.X + " Y=" + rightHandPos.Y);
        }

        EventHandler<IvyMessageEventArgs> rightHandEvent = new EventHandler<IvyMessageEventArgs>(t3);
        static void t3(Object o, IvyMessageEventArgs a)
        {
            String arg = a.GetArguments()[0];
            if (arg.Equals("OPENED"))
            {
                switch (etat)
                {
                    case States.LIBRE:
                        rightHandOpened = true;
                        break;
                    case States.EFFACE:
                        // Interdit
                        break;
                    case States.DESSIN:
                        rightHandOpened = true;
                        etat = States.EFFACE;
                        send("KINECT_STATE=EFFACE");
                        break;
                }
            }
            else if (arg.Equals("CLOSED"))
            {
                switch (etat)
                {
                    case States.LIBRE:
                        rightHandOpened = false;
                        break;
                    case States.EFFACE:
                        rightHandOpened = false;
                        etat = States.DESSIN;
                        send("KINECT_STATE=DESSIN");
                        break;
                    case States.DESSIN:
                        // Interdit
                        break;
                }
            }
            else if (arg.Equals("CLICK"))
            {
                switch (etat)
                {
                    case States.LIBRE:
                        // Interdit
                        break;
                    case States.EFFACE:
                        send("KINECT_EVENT=CLEAN");
                        etat = States.LIBRE;
                        send("KINECT_STATE=LIBRE");
                        break;
                    case States.DESSIN:
                        etat = States.LIBRE;
                        send("KINECT_STATE=LIBRE");
                        break;
                }
            }
            else if (arg.Equals("WAVE"))
            {
                switch (etat)
                {
                    case States.LIBRE:
                        if (rightHandOpened)
                        {
                            etat = States.EFFACE;
                            send("KINECT_STATE=EFFACE");
                        }
                        else
                        {
                            etat = States.DESSIN;
                            send("KINECT_STATE=DESSIN");
                        }
                        break;
                    case States.EFFACE:
                        // Interdit
                        break;
                    case States.DESSIN:
                        // Interdit
                        break;
                }
            }
        }

        private static void getReady()
        {
            window.majFeedbackConnection(displayReady, kinectReady);
            Console.WriteLine("Vue prête : " + displayReady);
            Console.WriteLine("Kinect prête : " + kinectReady);
            //if (displayReady && kinectReady) send("KINECT_EVENT=KINECT_READY");
            if (kinectReady) send("KINECT_EVENT=KINECT_READY");
        }

        private static void send(String s)
        {
            bus.SendMsg(s);
        }
    }
}
